package com.ruoyi.framework.web.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.constant.PointsConstants;
import com.ruoyi.common.constant.PrizeLevelConstants;
import com.ruoyi.common.constant.PrizeTypeConstants;
import com.ruoyi.common.core.domain.DTO.*;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.BO.SaveUserPrizeRecordBO;
import com.ruoyi.system.mapper.PrizePoolMapper;
import com.ruoyi.system.mapper.PurchaseRecordMapper;
import com.ruoyi.system.mapper.SignInStatisticsMapper;
import com.ruoyi.system.mapper.UserPrizeRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
@Transactional
public class PrizeService {
    @Autowired
    private PrizePoolMapper prizePoolMapper;

    @Autowired
    private UserPrizeRecordMapper userPrizeRecordMapper;

    @Autowired
    private PointsService pointsService;

    @Autowired
    private PurchaseRecordMapper purchaseRecordMapper;

    @Autowired
    private InviteRecordService inviteRecordService;

    @Autowired
    private SignInStatisticsMapper signInStatisticsMapper;

    /**
     * 添加奖池
     */
    public void add(AddPrizePoolBO addPrizePoolBO) {
        PrizePool prizePool = new PrizePool();
        BeanUtils.copyProperties(addPrizePoolBO, prizePool);
        prizePool.setStatus(1);
        prizePool.setCreateTime(new Date());
        prizePool.setUpdateTime(new Date());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        prizePool.setCreator(user.getUserName());
        prizePool.setModifier(user.getUserName());
        prizePoolMapper.insertPrizePool(prizePool);
    }

    /**
     * 修改奖池
     */
    public void update(UpdatePrizePoolBO updatePrizePoolBO) {
        PrizePool prizePool = new PrizePool();
        BeanUtils.copyProperties(updatePrizePoolBO, prizePool);
        prizePool.setUpdateTime(new Date());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        prizePool.setModifier(user.getUserName());
        prizePoolMapper.updatePrizePool(prizePool);
    }

    /**
     * 启用/禁用奖池
     */
    public void updateStatus(UpdateStatusBO updateStatusBO) {
        PrizePool prizePool = new PrizePool();
        prizePool.setId(updateStatusBO.getId());
        prizePool.setStatus(updateStatusBO.getStatus());
        prizePoolMapper.updatePrizePool(prizePool);
    }

    /**
     * 查询奖品池
     */
    public List<PrizePool> selectPrizePoolList(Integer level) {
        return prizePoolMapper.selectPrizePoolList(level);
    }

    /**
     * 保存中奖记录
     */
    public UserPrizeRecordVO saveUserPrizeRecord(SaveUserPrizeRecordBO saveUserPrizeRecordBO) {
        Long userId = saveUserPrizeRecordBO.getUserId();
        Long prizeId = saveUserPrizeRecordBO.getPrizeId();
        //查询奖池详情
        PrizePool prizePool = prizePoolMapper.selectPrizePoolById(prizeId);
        if (ObjectUtils.isEmpty(prizePool)) {
            throw new RuntimeException("奖品不存在");
        }
        updateLotteryCount(userId, prizePool.getPrizeLevel());
        //查询并更新用户抽奖次数
        if (prizePool.getPrizeLevel().equals(PrizeLevelConstants.THIRD_LEVEL) && prizePool.getPrizeType().equals(PrizeTypeConstants.POINTS)) {
            int points = 0;
            //计算提成积分
            //获取直属下级人员id
            List<Long> directUserIds = inviteRecordService.selectDirectTeamUserIds(userId);
            //获取团队下2级之后12级之内人员id
            List<Long> teamUserIds = inviteRecordService.selectTeamUserIds(userId);
            //团队id去掉直属下级人员id
            teamUserIds.removeAll(directUserIds);
            //查询上周团队人员出单量
            //获取上周一周的开始时间
            Date startTime = DateUtils.getLastWeekMonday();
            //获取上周日的结束时间
            Date endTime = DateUtils.getLastWeekSunday();
            Integer directUserOrderCount = 0;
            if(!ObjectUtils.isEmpty(directUserIds)){
                directUserOrderCount = purchaseRecordMapper.selectCountByUserIds(directUserIds, startTime, endTime);
            }
            Integer teamUserOrderCount = 0;
            if(!ObjectUtils.isEmpty(teamUserIds)){
                teamUserOrderCount = purchaseRecordMapper.selectCountByUserIds(teamUserIds, startTime, endTime);
            }
            if (teamUserOrderCount == 0 && directUserOrderCount == 0) {
                log.info("未中奖，本周团队无出单");
                throw new RuntimeException("未中奖，本周团队无出单");
            }
            if (teamUserOrderCount > 0) {
                int teamPoints = teamUserOrderCount * PointsConstants.FIVE_POINTS;
                points += teamPoints;
                log.info("用户{}团队积分: {} (订单数: {})", userId, teamPoints, teamUserOrderCount);
            }
            if (directUserOrderCount > 0) {
                int directUserPoints = directUserOrderCount * PointsConstants.ONE_THOUSAND_POINTS;
                points += directUserPoints;
                log.info("用户{}的直属下级团队获得积分: {} (订单数: {})", userId, directUserPoints, directUserOrderCount);
            }
            prizePool.setPrizeAmount(new BigDecimal(points));
        }
        //保存中奖记录
        UserPrizeRecord userPrizeRecord = new UserPrizeRecord();
        userPrizeRecord.setUserId(userId);
        userPrizeRecord.setPoolId(prizeId);
        userPrizeRecord.setPrizeName(prizePool.getName());
        userPrizeRecord.setPrizeType(prizePool.getPrizeType());
        userPrizeRecord.setPrizeAmount(prizePool.getPrizeAmount());
        userPrizeRecord.setWinningTime(new Date());
        userPrizeRecord.setStatus(1);
        userPrizeRecord.setReceiveTime(new Date());
        userPrizeRecordMapper.saveUserPrizeRecord(userPrizeRecord);
        //更新用户积分
        if (prizePool.getPrizeType() == 2) {
            UpdateUserPointsAndLogBO updateUserPointsAndLogBO = new UpdateUserPointsAndLogBO();
            updateUserPointsAndLogBO.setUserId(userId);
            updateUserPointsAndLogBO.setPoints(prizePool.getPrizeAmount().intValue());
            updateUserPointsAndLogBO.setPointsType(1);
            updateUserPointsAndLogBO.setSource("中奖");
            updateUserPointsAndLogBO.setRelatedOrderNo(userPrizeRecord.getId().toString());
            updateUserPointsAndLog(updateUserPointsAndLogBO);
        }
        UserPrizeRecordVO userPrizeRecordVO = new UserPrizeRecordVO();
        BeanUtils.copyProperties(prizePool, userPrizeRecordVO);
        userPrizeRecordVO.setPrizeName(prizePool.getName());
        return userPrizeRecordVO;
    }

    //更新用户积分并保存积分记录
    public void updateUserPointsAndLog(UpdateUserPointsAndLogBO updateUserPointsAndLogBO) {
        Long userId = updateUserPointsAndLogBO.getUserId();
        Integer point = updateUserPointsAndLogBO.getPoints();
        Integer pointsType = updateUserPointsAndLogBO.getPointsType();
        String source = updateUserPointsAndLogBO.getSource();
        String relatedOrderNo = updateUserPointsAndLogBO.getRelatedOrderNo();
        UserPoints userPoints = pointsService.selectUserPointsByUserId(userId);
        if (ObjectUtils.isEmpty(userPoints)) {
            UserPoints points = new UserPoints();
            points.setUserId(userId);
            points.setTotalPoints(point);
            points.setAvailablePoints(point);
            points.setFrozenPoints(0);
            points.setExpiredPoints(0);
            points.setLevel(1);
            pointsService.insertUserPoints(points);
        } else {
            Integer totalPoints = userPoints.getTotalPoints() + point;
            userPoints.setTotalPoints(totalPoints);
            userPoints.setAvailablePoints(userPoints.getAvailablePoints() + point);
            pointsService.updateUserPoints(userPoints);
        }
        //添加积分变更记录
        UserPointsLog userPointsLog = new UserPointsLog();
        userPointsLog.setUserId(userId);
        userPointsLog.setChangeType(1);
        userPointsLog.setChangeValue(point);
        // TODO 积分类型
        userPointsLog.setPointsType(pointsType);
        userPointsLog.setSource(source);
        userPointsLog.setRelatedOrderNo(relatedOrderNo);
        userPointsLog.setCreateTime(new Date());
        pointsService.insertUserPointsLog(userPointsLog);
    }

    public void updateLotteryCount(Long userId,Integer prizeLevel){
        //查询用户剩余抽奖次数
        int lotteryCount = signInStatisticsMapper.getLotteryCount(userId,prizeLevel);
        if (lotteryCount <= 0) {
            throw new RuntimeException("剩余抽奖次数不足，抽奖失败");
        }
        //用户对应等级抽奖次数-1
        signInStatisticsMapper.updateLotteryCount(userId,prizeLevel);
    }

    /**
     * 查询用户中奖记录
     */
    public List<UserPrizeRecord> selectUserPrizeRecordList(Long userId) {
        return userPrizeRecordMapper.selectUserPrizeRecordList(userId);
    }

    /**
     * 使用奖品
     */
    public void cashOut(Long id) {
        UserPrizeRecord userPrizeRecord = userPrizeRecordMapper.selectUserPrizeRecordById(id);
        if (ObjectUtils.isEmpty(userPrizeRecord)) {
            throw new RuntimeException("未查询到中奖记录");
        }
        userPrizeRecord.setStatus(3);
        userPrizeRecordMapper.updateUserPrizeRecord(userPrizeRecord);
    }
}
